﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IM.gerenciadores
{
    public class GerenciadorDeCodificacao
    {
        enum TipoConversao { CODIFICADOR, DECODIFICADOR };

        public static String codificaString(String mensagem)
        {
            return codificacaoFibonnaciString(mensagem, TipoConversao.CODIFICADOR);
        }

        public static String decodificaString(String mensagem)
        {
            return codificacaoFibonnaciString(mensagem, TipoConversao.DECODIFICADOR);
        }

        private static String codificacaoFibonnaciString(String mensagem, TipoConversao tipo)
        {
            String resposta = "";
            int fibonnaci = 1;
            int primeiro = 0;
            int segundo = 1;
            char[] caracteres = mensagem.ToCharArray();
            foreach (char c in caracteres)
            {
                char ch = ' ';
                switch (tipo)
                {
                    case TipoConversao.CODIFICADOR:
                        ch = (char)(((int)c) + fibonnaci);
                        break;
                    case TipoConversao.DECODIFICADOR:
                        ch = (char)(((int)c) - fibonnaci);
                        break;
                }
                resposta += ch.ToString();

                fibonnaci = primeiro + segundo;
                primeiro = segundo;
                segundo = fibonnaci;

                if (fibonnaci > 10946)
                {
                    fibonnaci = 1;
                    primeiro = 0;
                    segundo = 1;
                }
            }
            return resposta;
        }


        public static byte[] codificaArquivo(byte[] arquivo)
        {
            return codificacaoFibonnaciArquivo(arquivo);
        }

        public static byte[] decodificaArquivo(byte[] arquivo)
        {
            return codificacaoFibonnaciArquivo(arquivo);
        }

        private static byte[] codificacaoFibonnaciArquivo(byte[] original)
        {
            byte[] resposta = new byte[original.Length];
            int fibonnaci = 1;
            int primeiro = 0;
            int segundo = 1;
            int count = 0;
            foreach (byte b in original)
            {
                byte byteRetorno = Convert.ToByte(255 - ((int)b));
                
                resposta[count] = byteRetorno;
                count++;

                fibonnaci = primeiro + segundo;
                primeiro = segundo;
                segundo = fibonnaci;

                if (fibonnaci > 10946)
                {
                    fibonnaci = 1;
                    primeiro = 0;
                    segundo = 1;
                }
            }
            return resposta;
        }
    }
}
